package mymyoux.io.sql
{
	import flash.data.SQLResult;
	import flash.data.SQLStatement;
	import flash.errors.SQLError;
	import flash.events.SQLErrorEvent;
	import flash.events.SQLEvent;
	
	import mx.rpc.events.ResultEvent;
	
	import mymyoux.signals.Signal;

	public class SQLQuery
	{
		private var _querys:Vector.<String>;
		private var _listeners:Vector.<Function>;
		private var _parameters:Vector.<Array>;
		private var _sql:SQL;
		private var _query:String;
		private var _sqlQuery:SQLStatement;
		private var _signalResult:Signal;
		private var _signalError:Signal;
		public function SQLQuery()
		{
			_query = "";
			_querys = new Vector.<String>();
			_listeners = new Vector.<Function>();
			_parameters = new Vector.<Array>();
			_signalResult = new Signal(SQLResult);
			_signalError = new Signal(SQLError);
			 
			_sqlQuery = new SQLStatement();
			_sqlQuery.addEventListener(SQLEvent.RESULT, onResult);
			_sqlQuery.addEventListener(SQLErrorEvent.ERROR, onError);
		}

		public function get signalError():Signal
		{
			return _signalError;
		}

		public function get signalResult():Signal
		{
			return _signalResult;
		}

		public function get sql():SQL
		{
			return _sql;
		}

		public function set sql(value:SQL):void
		{
			if(_sql != null)
			{
				_sql.signalOpen.remove(onSqlConnect);
			}
			_sql = value;
			if(_sql != null)
			{
				_sql.signalOpen.add(onSqlConnect);
				if(_sql.connected)
				{
					onSqlConnect();
				}
			}		
		}
		public function query(query:String, listener:Function = null, ...parameters):void
		{
			if(query != null && query.length > 0)
			{
				_query = query;
				_querys.push(query);
				_listeners.push(listener);
				_parameters.push(parameters);
			}
		}
		public function execute(query:String = null, listener:Function = null, ...parameters):void
		{
			trace("execute");
			var args:Array = new Array();
			args.push(query, listener);
			this.query.apply(this, args.concat(parameters));
			if(_querys.length > 0)
			{
				_query = _querys[0];
				if(_sql != null && _sql.connected && _query != null && _query.length > 0 && !_sqlQuery.executing)
				{
					_sqlQuery.sqlConnection = _sql.sqlConnection;
					_sqlQuery.text = _query;
					_sqlQuery.execute();
				}
			}
		}
		private function onResult(event:SQLEvent):void
		{
			trace(event);
			_querys.shift();
			var listener:Function = _listeners.shift();
			var result:SQLResult = _sqlQuery.getResult();
			if(listener != null)
			{
				var args:Array = new Array();
				args.push(new SQLQueryEvent(result));
				listener.apply(this, args.concat(_parameters.shift()));
			}
			signalResult.dispatch(_sqlQuery.getResult());
			
			execute();
		}
		private function onError(event:SQLErrorEvent):void
		{
			
			trace(event);
			_querys.shift();
			var listener:Function = _listeners.shift();
			if(listener != null)
			{
				var args:Array = new Array();
				args.push(new SQLQueryEvent(null, event.error));
				listener.apply(this, args.concat(_parameters.shift()));
			}
			signalError.dispatch(event.error);
			execute();
		}
		private function onSqlConnect():void
		{
			trace("sql connected");
			execute();
		}
	}
}